#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/bitypes.h>
#include<sys/wait.h>


#define NUM 1024
#define SIZE 100
#define SEP_SYMBOL " "


//获取机主用户名
const char* GetUserName()
{
    const char* name = getenv("USER");//从系统自带的环境变量接口处获取机主用户名
    if(!name)return "none";
    else return name;
}
//获取主机名
const char* GetHostName()
{
    const char* hostname = getenv("HOSTNAME");//从系统自带的环境变量接口处获取主机名
    if(!hostname)return "none";
    else return hostname;
}
//获取工作目录
const char* GetCwd()
{  
    const char* cwd = getenv("PWD");//从系统自带的环境变量接口处获取当前工作目录
    if(!cwd)return "none";
    else return cwd;
}

int GetUserCommand(char* command,int len)
{
    printf("[%s@%s %s]# ",GetUserName(),GetHostName(),GetCwd());

    //scanf("%s",usercommand);//只能获取空格前的字符串
    
    char* ret=fgets(command,len,stdin);//从键盘上获取字符串，并将得到的字符串放在usercommand数组中
    //判断获取成功与否
    if(ret==NULL) return 1;
    
    //"abcdef\n"  得到的字符串的最后位置有一个“本不想要的\n” 如何去掉?
    command[strlen(command)-1]='\0';
}

//分割字符串
void Split_string(char* string,char** argv)
{
    int argc=0;
    argv[argc++]=strtok(string,SEP_SYMBOL);
    while(argv[argc++]=strtok(NULL,SEP_SYMBOL));


    //打印看看效果
   // for(int i=0;argv[i];i++)
   // {
   //     printf("%s\n",argv[i]);
   // }
}

void Execute_process(char* argv[])
{
    pid_t id=fork();
    if(id<0)return ;
    else if(id==0)
    { 
        //子进程
        execvp(argv[0],argv);//第一个参数：执行什么命令  第二个参数：以什么方式执行

        exit(1); 
    }
    else  
    {
        //父进程
        pid_t rid=waitpid(id,NULL,0);
    
        if(rid>0)
        {
            //等待成功
        }
        else 
        {
            //等待失败
        }
    }       
}

void cd(char* path)
{
    chdir(path);
}

void Do_Built_Command(char** argv)
{
    if(strcmp(argv[0],"cd")==0)
    {
        char* path=NULL;
        if(argv[1]==NULL)path=".";
        else path=argv[1];
        cd(path);
    }
}

int main()
{
    while(1)
    {
         char usercommand[NUM];
         char* argv[SIZE];

         //1.打印提示符 && 获取用户命令字符串
         GetUserCommand(usercommand,sizeof(usercommand));
         
         //2.分割字符串
         Split_string(usercommand,argv);

         //3.执行内建命令
         Do_Built_Command(argv);

         //4.开始执行命令 --- 程序替换 
         //不能直接让本进程执行命令  因为其会把我们的代码都覆盖掉  所以需要创建一个子进程
         Execute_process(argv);
    }
    return 0;
}
